package cz.muni.fi.pa165.web.webservice.controller;

import cz.muni.fi.pa165.api.ForestService;
import cz.muni.fi.pa165.api.ForestVisitService;
import cz.muni.fi.pa165.api.dto.ForestDTO;
import cz.muni.fi.pa165.api.dto.ForestVisitDTO;
import cz.muni.fi.pa165.webservice.ForestWebServiceAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 *
 * @author Matej Cimbora
 */
@Controller
public class JsonForestController implements ForestWebServiceAPI {

    @Autowired
    private ForestService forestService;
    @Autowired
    private ForestVisitService forestVisitService;

    @Override
    @RequestMapping(value = {"json/createForest*"}, method = RequestMethod.POST)
    public @ResponseBody
    void createForest(@RequestBody ForestDTO forestDTO) {
        setAuth();
            forestService.createForest(forestDTO);
        }

    @Override
    @RequestMapping(value = {"/json/getForest*"}, method = RequestMethod.GET)
    public @ResponseBody
    ForestDTO getForest(@RequestParam String id) {
        setAuth();
        return forestService.getForest(Long.valueOf(id));
    }

    @Override
    @RequestMapping(value = {"json/updateForest*"}, method = RequestMethod.POST)
    public @ResponseBody
    void updateForest(@RequestBody ForestDTO forestDTO) {
        setAuth();
        forestService.updateForest(forestDTO);
    }

    @Override
    @RequestMapping(value = {"json/removeForest*"}, method = RequestMethod.POST)
    public @ResponseBody
    void removeForest(@RequestBody ForestDTO forestDTO) {
        setAuth();
        for (ForestVisitDTO fv : forestVisitService.retrieveVisitsByForest(forestDTO)) {
            forestVisitService.removeVisit(fv);
        }
        forestService.removeForest(forestDTO);
    }

    /*
     * Array used instead of list because RestTemplate does not provide sufficient
     * support of generic types
     */
    @Override
    @RequestMapping(value = {"json/getAllForests"}, method = RequestMethod.GET)
    public @ResponseBody
    ForestDTO[] retrieveAllForests() {
        setAuth();
        return (ForestDTO[]) forestService.retrieveAllForests().toArray(new ForestDTO[0]);
    }

    @Override
    @RequestMapping(value = {"json/getByName*"}, method = RequestMethod.GET)
    public @ResponseBody
    ForestDTO retrieveForestByName(@RequestParam String name) {
        setAuth();
        return forestService.retrieveForestByName(name);
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public String handleException1(Exception ex) {
        return null;
    }
    
    public void setAuth() {
        Authentication auth = new UsernamePasswordAuthenticationToken("rest", "rest");
        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(auth);
    }
}
